home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 151-175 / scopedisk165 / rexxgenlock / genlock.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  11KB  |  361 lines

  1. /* GENLOCK v.02 */
  2.                   /*******************************/
  3.                   /* GENLOCK */   /* Version .02 */
  4.                   /* Oct. 6, 1990               */
  5.                   /* by Robert Dickow            */
  6.                   /*    1102 E. Sixth St.        */
  7.                   /*    Moscow, ID  83843        */
  8.                   /*    (208)-882-9117           */
  9.                   /*    dickow@idui1 (BITNET)    */
  10.                   /*******************************/
  11.  
  12.          /*************************************************/
  13.          /*                                               */
  14.          /*  This program allows ARexx control of         */
  15.          /*  Digital Creations SuperGen genlock video     */
  16.          /*  overlay device. This device has manual       */
  17.          /*  controls and comes with hot key and joystick */
  18.          /*  control interfaces. What I needed was some   */
  19.          /*  way to control the genlock from cli/rexx     */
  20.          /*  and programs such as The Director, which has */
  21.          /*  no 'native' genlock control features at this */
  22.          /*  writing. Hence this program.                 */
  23.          /*                                               */
  24.          /*************************************************/
  25.  
  26. /*--***---***---***---***---***---***---***---***---***---***---***---***--*/
  27. /*                                                                         */
  28. /* Needed to compile this program: ANSII C compiler (Manx 5.0a used here)  */
  29. /*                                 minrexx.c, minrexx.h (from Radical Eye  */
  30. /*                                 but in public domain), supergen.h       */
  31. /*                                 (comes with SuperGen genlock software), */
  32. /*                                 copinit.h (nested in supergen.h)        */
  33. /* Needed to link this program:    Manx 5.0a, dc.lib (comes w/SuperGen),   */
  34. /*                                 c.lib (standard Manx c library, and     */
  35. /*                                 rexxglue.o (comes w/minrexx.c stuff)    */
  36. /* Needed to execute this program: in libs: supergen.library and           */
  37. /*                                 copinit.library, plus the usual rexx    */
  38. /*                                 library stuff to run Arexx, but if you  */
  39. /*                                 plan to get DOS2.0, you will get these  */
  40. /*                                 things already anyhoo.                  */
  41. /*                                                                         */
  42. /*--***---***---***---***---***---***---***---***---***---***---***---***--*/
  43.  
  44. #include <stdio.h>     /* ...the usual stuff.             */
  45. #include "minrexx.c"   /* Thanks to Radical Eye Software! */
  46. #include <exec/exec.h>
  47. #include <ctype.h>
  48. #include <limits.h>
  49. #include <DCInterface/supergen.h> /* N.B: nested include of copinit.h here */
  50.  
  51. /***************************************************************/
  52. /* Control the genlock:                                        */
  53. /***************************************************************/
  54.  
  55. #define GEN_ON   1L     /* Masks... */
  56. #define GEN_OFF  0L
  57.  
  58. #define MAXPRIORITY 8
  59. #define MINPRIORITY 0
  60.  
  61. /* Error flags for sending to cleanup() */
  62. #define COULDNT_OPEN_SGENLIB  1
  63.  
  64. /*--declarations:----------------------------------------------------------*/
  65. /* AREXX STUFF...                                                          */
  66. /* The following are some declarations needed for the ARexx port:          */
  67.  
  68. char * PortName = "genlock";    /* Name of Rexx msgport for ADDRESS.       */
  69. long PortBit;                   /* For ARexx signal bit.                   */
  70. char * Extension= ".rexx";        /* For default ARexx file extension        */
  71. char * ExtU = "-E";
  72. char * ExtL = "-e";
  73.  
  74. /* This is the declarations and list of acceptable commands from ARexx
  75.    (and from the CLI as well, but CLI commands are processed separately.)
  76.    The behavior from CLI is execute-and-exit unless
  77. */
  78.  
  79. void RXcmd_quit(void);
  80. void RXcmd_Genlock_ON(void), RXcmd_Genlock_OFF(void);
  81. void RXcmd_Priority(void), RXcmd_CallPriority(void);
  82.  
  83. struct rexxCommandList cmds[] =  {
  84.   { "quit", (APTR) &RXcmd_quit },
  85.   { "genpri",(APTR) &RXcmd_Priority },
  86.   { "on",(APTR) &RXcmd_Genlock_ON },
  87.   { "off",(APTR) &RXcmd_Genlock_OFF },
  88.   { "callpri",(APTR) &RXcmd_CallPriority },
  89.   { NULL, NULL  }
  90.   };
  91.  
  92. /* Genlock control stuff...                                         */
  93.  
  94. APTR SuperGenBase= NULL, CopinitBase;
  95.  
  96. void SuperGen(long Flags, int BackGroundValue, int BGnoVB,
  97.               int GraphicsValue, int GnoVB);
  98. void SuperGenPriority(int Level, int SetLevel);
  99. long StatusGen(void);
  100.  
  101. int PriorityLevel(void);
  102. void cleanup(int);
  103.  
  104. /*-------------------------------------------------------------------*/
  105. /* These are some declarations for the general application:          */
  106.  
  107. /* extern void Wait(long); */
  108.  
  109. #define QUIT_REQ 1
  110. #define HELP_REQ 2
  111.  
  112. int errorcode=0;
  113. int all_done=0; /* flag to tell main loop that a quit request is in. */
  114.  
  115. char *CLIHelp[] = { "-H", "-?", "?", "HELP", "-HELP", NULL };
  116.  
  117. int rx_args[4] =           /* what args did we get to the command?   */
  118.   { 0, -1, 0, -1 };
  119. int parsed ;               /* # of arguments passed via arexx.       */
  120. void parseargs(char *p, int n);
  121. char returnstr[3]= { 0, 0, 0 };
  122. char *returnbuffer = NULL;
  123. long CallPriority=(long) MAXPRIORITY;
  124. /*-------------------------------------------------------------------*/
  125.  
  126. /* main() initializes the RexxPort via minrexx.c routines, then waits
  127.           in a loop for more commands until QUIT is issued. If the
  128.           program is executed from the CLI, the REXX polling loop is
  129.           entered only if the CLI command line has the HOLD option flag
  130.           after any CLI option, or if the program is called with no
  131.           command line arguments at all or just HOLD.
  132.           See the READ.ME file for additional CLI and rexx addressable
  133.           commands options.
  134. */
  135.  
  136. main(int ncarg, char ** carg)
  137. {
  138.   void RXcmd_handler(struct RexxMsg *, struct rexxCommandList *,char *);
  139.   void init_SuperGen(void);
  140.   int  check_state(char *, char **,int ncrg);
  141.  
  142.   if (check_state( * (carg+1), carg, ncarg) == FALSE) {
  143.     init_SuperGen();
  144.  
  145.     PortBit = upRexxPort(PortName,cmds,Extension,&RXcmd_handler);
  146.     while (! all_done) {
  147.       Wait (PortBit);
  148.       dispRexxPort();
  149.     }
  150.     cleanup(errorcode);
  151.   }
  152. }
  153.  
  154.  
  155. /* If the user initiates this driver ("genlock") with no argument but
  156.    the program is already resident, then nothing will happen.
  157.    If the user types the arguments "-h", "-?", "help", or "?" then
  158.    a brief help message will be printed and the program will exit. ALL
  159.    other arguments are processed, if recognized as genlock commands, or
  160.    passed to rexx for further processing.
  161. */
  162.  
  163. int check_state(char * typed, char ** carg,int ncrg)
  164. {
  165.   char namebuff[81];
  166.   int parseCLIRequest(char * typed, char **,int ncrg);
  167.   int returnval;
  168.  
  169.   returnval = parseCLIRequest(typed, carg, ncrg);
  170.   if (returnval == HELP_REQ) {
  171.     printf ("\nFrom CLI at any time: genlock [help] | [quit]\n");
  172.     printf ("From CLI at initialization: genlock [help] | [-e .extstr]\n");
  173.     printf ("From rexx: rx genlock[.ext] ON BackGroundValue BGnoVB GraphicsValue GnoVB\n");
  174.     printf ("                            OFF BackGroundValue BGnoVB GraphicsValue GnoVB\n");
  175.     printf ("                            GENPRI <0 - 8>\n");
  176.     printf ("                            CALLPRI <0 - 8>\n");
  177.     printf ("                            QUIT\n");
  178.     returnval = TRUE;
  179.   } else if (returnval == QUIT_REQ) {
  180.       if (FindPort(PortName) != NULL) {
  181.         strcpy (namebuff,"genlock");
  182.         strcat (namebuff,Extension);
  183.         execlp ("rx"," ",namebuff," ","quit"," ",NULL);
  184.         returnval = TRUE;
  185.         }
  186.     } else if (FindPort(PortName) != NULL) {
  187.          returnval = TRUE;
  188.       } else
  189.         returnval = FALSE;
  190.   return (returnval);
  191. }
  192.  
  193. /* This just sees if cmd line arg is a valid help or quit request... */
  194.  
  195. int parseCLIRequest(char * typed, char ** carg,int ncrg)
  196. {
  197.   char buff[81];
  198.   int n, index, ishelp, x;
  199.   char *str;
  200.  
  201.   ishelp = 0;
  202.   if (strlen (typed) <= 80) {
  203.     (void) strcpy(buff,typed);
  204.     n = strlen (buff);
  205.     for (x=0;x<n;x++)
  206.      *(buff+x) = toupper(*(buff+x));
  207.     index = 0;
  208.     while (str = *(CLIHelp+index++)) {
  209.       if (strcmp (buff,str)==0) {
  210.         ishelp = HELP_REQ;
  211.         break;
  212.       }
  213.     }
  214.     if (strcmp(buff,"QUIT")==0) {
  215.       ishelp = QUIT_REQ;
  216.     } else {
  217.       index = 1;
  218.       while (index++ < ncrg) {
  219.         if (strcmp(ExtL,*(carg+index))==0 || strcmp(ExtU,*(carg+index))==0) {
  220.           if (FindPort(PortName) == NULL)
  221.             Extension = *(carg+(++index));
  222.         }
  223.       }
  224.     }
  225.   }
  226.   return (ishelp);
  227. }
  228.  
  229. /* If Rexx sends a command to this program via the AREXX Port, this routine
  230.    is vectored to handle those commands.
  231. */
  232. void RXcmd_handler(struct RexxMsg *msg, struct rexxCommandList *dat, char *p)
  233. {
  234.   int x;
  235.  
  236.   returnbuffer = NULL;
  237.   parseargs((char *)msg->rm_Args[0],4);
  238.   ((int (*)())(dat->userdata))() ;
  239.   replyRexxCmd(msg, 0L, 0L, returnbuffer);
  240. }
  241.  
  242.  
  243. /* rexx command routine to set a flag to signal main() loop that
  244.    an exit from the loop has been requested.
  245. */
  246. void RXcmd_quit(void)
  247. {
  248.   all_done = 1;
  249. }
  250.  
  251. void init_SuperGen(void)
  252. {
  253.  
  254.   if ((SuperGenBase=(APTR) OpenLibrary("supergen.library",0L)) == NULL)
  255.     cleanup(COULDNT_OPEN_SGENLIB);
  256.   SuperGenPriority(MAXPRIORITY,TRUE);
  257. }
  258.  
  259. void cleanup(int errorcode)
  260. {
  261.   dnRexxPort();
  262.   if (SuperGenBase != (long) NULL) {
  263.     RXcmd_Genlock_OFF();
  264.     CloseLibrary(SuperGenBase);
  265.   }
  266.   exit(errorcode);
  267. }
  268.  
  269. /* Clip passed value to n<9>=0 */
  270. int clip(int val)
  271. {
  272.     if (val > 8)
  273.       val = 8;
  274.     else if (val < 0)
  275.       val = 0;
  276.     return val;
  277. }
  278.  
  279. int PriorityLevel(void)
  280. {
  281.   int value;
  282.   int count = 0;
  283.  
  284.   value = ((int)((StatusGen() >>24 ) & 0xff)) ;
  285.   while (value != 0)
  286.     value >>= 1, count++;
  287.   return (count);
  288. }
  289.  
  290. void Gen_Priority (void)
  291. {
  292.   sprintf ((char *)&returnstr, "%1d",PriorityLevel());
  293.   returnbuffer = (char * )&returnstr;
  294. }
  295.  
  296. void Gnlck(long Flags)
  297. {
  298.   Flags =  Flags | (CallPriority << 16) ;
  299.   SuperGen(Flags,rx_args[0],rx_args[1],rx_args[2],rx_args[3]);
  300. }
  301.  
  302. void RXcmd_CallPriority(void)
  303. {
  304.   int val;
  305.  
  306.   if (parsed >0) {
  307.     val = clip(rx_args[0]);
  308.     CallPriority = val;
  309.   } else {
  310.     sprintf ((char *)&returnstr, "%1d",CallPriority);
  311.     returnbuffer = (char * )&returnstr;
  312.   }
  313. }
  314.  
  315. void RXcmd_Genlock_ON(void)
  316. {
  317.   Gnlck (GEN_ON);
  318. }
  319.  
  320. void RXcmd_Genlock_OFF(void)
  321. {
  322.   Gnlck (GEN_OFF);
  323. }
  324.  
  325. void RXcmd_Priority(void)
  326. {
  327.   int val;
  328.  
  329.   if (parsed >0) {
  330.     val = rx_args[0];
  331.     val = clip(val);
  332.     SuperGenPriority(PriorityLevel(),FALSE);  /* clear it! */
  333.     SuperGenPriority( val,TRUE);              /* set new priority level */
  334.   } else if (parsed == 0)
  335.       Gen_Priority();
  336. }
  337.  
  338. /*
  339.  *   This function tries to find `n' signed numeric arguments in the command
  340.  *   string, and stuffs them into the rx_args array.
  341.  */
  342. void parseargs(char *p, int n)
  343. {
  344.    register int i ;
  345.    int x=0;
  346.    char *first_tok;
  347.    char *tok;
  348.    char * strtok(char *,char *);
  349.  
  350.    while (*p > ' ' && *p)
  351.       p++ ;
  352.    first_tok = p;
  353.    while (((tok=strtok(first_tok," ")) != NULL) && (x < n)) {
  354.      rx_args[x] = atoi(tok);
  355.      first_tok = NULL;
  356.      x++;
  357.    }
  358.    parsed = x;
  359. }
  360.  
  361.